package com.bf.electroplating.util.easyexcel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.bf.electroplating.pojo.entity.ControlProblemRenovate;
import com.bf.electroplating.pojo.entity.ControlRenovateRectification;
import com.bf.electroplating.pojo.enums.AttModuleEnums;
import com.bf.electroplating.service.ControlProblemRenovateService;
import com.bf.electroplating.service.ControlRenovateRectificationService;
import com.bf.electroplating.service.PubAttachmentService;
import com.bf.electroplating.util.easyexcel.excel.rectification.RectificationDataExcel;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 整改数据Excel监听器
 */
@Slf4j
@Component
public class RectificationDataExcelListener extends AnalysisEventListener<RectificationDataExcel> {
    
    @Resource
    private ControlProblemRenovateService controlProblemRenovateService;
    


    @Resource
    private ControlRenovateRectificationService controlRenovateRectificationService;
    @Resource
    private PubAttachmentService pubAttachmentService;
    
    /**
     * 每隔100条存储数据库，然后清理list，方便内存回收
     */
    private static final int BATCH_COUNT = 100;
    
    /**
     * 缓存的数据
     */
    private List<RectificationDataExcel> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    
    /**
     * 存储图片路径信息：key为"行号_列号"，value为图片保存路径
     * 由POI读取后传入
     */
    private Map<String, String> imagePathMap = new HashMap<>();
    
    /**
     * 企业ID（由外部传入）
     */
    private String companyId;
    
    /**
     * 重置监听器状态（每次导入前必须调用，清空上次导入的缓存）
     */
    public void reset() {
        if (cachedDataList != null) {
            cachedDataList.clear();
        }
        cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        
        if (imagePathMap != null) {
            imagePathMap.clear();
        }
        imagePathMap = new HashMap<>();
        
        companyId = null;
        
        log.info("监听器状态已重置");
    }
    
    /**
     * 设置图片路径Map（由外部POI读取后传入）
     */
    public void setImagePathMap(Map<String, String> imagePathMap) {
        this.imagePathMap = imagePathMap;
        log.info("监听器接收到{}张图片路径信息", imagePathMap.size());
    }
    
    /**
     * 设置企业ID
     */
    public void setCompanyId(String companyId) {
        this.companyId = companyId;
        log.info("监听器接收到企业ID: {}", companyId);
    }
    
    /**
     * 这个每一条数据解析都会来调用
     */
    @Override
    public void invoke(RectificationDataExcel data, AnalysisContext context) {
        try {
            // 获取当前行号（从0开始，但POI读图片时行号从0开始，第0行是表头）
            Integer currentRow = context.readRowHolder().getRowIndex();
            log.info("解析到一条整改数据：行号={}, 车间={}, 具体点位={}", currentRow, data.getWorkshop(), data.getSpecificLocation());
            
            // 整改前照片在第5列（index=4）
            String beforeImageKey = currentRow + "_" + 4;
            String beforeImagePath = imagePathMap.get(beforeImageKey);
            if (beforeImagePath != null && !beforeImagePath.isEmpty()) {
                data.setBeforeImagePath(beforeImagePath);
                log.info("找到整改前照片：{}", beforeImagePath);
            } else {
                log.debug("未找到整改前照片，key={}", beforeImageKey);
            }
            
            // 改造后照片在第7列（index=6）
            String afterImageKey = currentRow + "_" + 6;
            String afterImagePath = imagePathMap.get(afterImageKey);
            if (afterImagePath != null && !afterImagePath.isEmpty()) {
                data.setAfterImagePath(afterImagePath);
                log.info("找到改造后照片：{}", afterImagePath);
            } else {
                log.debug("未找到改造后照片，key={}", afterImageKey);
            }
            
            cachedDataList.add(data);
            
            // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
            if (cachedDataList.size() >= BATCH_COUNT) {
                saveData();
                // 注意：saveData()方法内部已经清空了cachedDataList
                log.info("已处理{}条数据，继续读取...", BATCH_COUNT);
            }
            
        } catch (Exception e) {
            log.error("处理整改数据异常", e);
        }
    }
    
    /**
     * 所有数据解析完成了都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有整改数据解析完成！");
        
        // 清空所有缓存（重要：防止下次导入时数据累积）
        if (cachedDataList != null) {
            cachedDataList.clear();
        }
        if (imagePathMap != null) {
            imagePathMap.clear();
        }
        companyId = null;
        
        log.info("监听器缓存已清空");
    }
    
    /**
     * 保存数据到数据库
     */
    private void saveData() {
        if (cachedDataList.isEmpty()) {
            return;
        }
        
        log.info("开始保存{}条整改数据到数据库", cachedDataList.size());
        
        int successCount = 0;
        int failCount = 0;
        
        for (RectificationDataExcel data : cachedDataList) {
            try {
                // 1. 创建整改问题记录 (ControlProblemRenovate)
                ControlProblemRenovate renovate = new ControlProblemRenovate();
                renovate.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                renovate.setProblemLocation(data.getWorkshop() + "-" + data.getSpecificLocation());
                renovate.setProblemDescription(data.getProblemDescription());
                renovate.setSuggest(data.getSuggestions());
                renovate.setRectificationStatus("1"); // 已完成
                renovate.setParkId("1001");
                renovate.setDelFlag("0");
                
                // 设置企业ID（如果传入了）
                if (companyId != null && !companyId.isEmpty()) {
                    renovate.setCompanyId(companyId);
                    log.info("设置企业ID: {}", companyId);
                }
                
                // 保存整改问题
                controlProblemRenovateService.save(renovate);
                log.info("保存整改问题成功，ID={}, 企业ID={}", renovate.getId(), companyId);
                
                // 2. 上传整改前照片并关联到整改问题
                if (data.getBeforeImagePath() != null && !data.getBeforeImagePath().isEmpty()) {
                    try {
                        String beforeAttId = pubAttachmentService.uploadFileFromPath(
                                data.getBeforeImagePath(), 
                                renovate.getId(),
                                AttModuleEnums.RENOVATE_PHOTO.getCode()); // 模块代码：整改前照片
                        log.info("整改前照片上传成功，附件ID={}", beforeAttId);
                    } catch (Exception e) {
                        log.error("整改前照片上传失败：{}", data.getBeforeImagePath(), e);
                    }
                }
                
                // 3. 创建整改记录 (ControlProblemRectification)
                ControlRenovateRectification rectification = new ControlRenovateRectification();
                rectification.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                rectification.setRId(renovate.getId()); // 关联整改问题
                rectification.setRectificationDescription(data.getRectificationContent());
                rectification.setRectificationTime(new java.util.Date());
                rectification.setDelFlag("0");
                // 保存整改记录
                controlRenovateRectificationService.save(rectification);
                log.info("保存整改记录成功，ID={}", rectification.getId());
                
                // 4. 上传改造后照片并关联到整改记录
                if (data.getAfterImagePath() != null && !data.getAfterImagePath().isEmpty()) {
                    try {
                        String afterAttId = pubAttachmentService.uploadFileFromPath(
                                data.getAfterImagePath(), 
                                rectification.getId(),
                                AttModuleEnums.RENOVATE_RECTIFICATION_PHOTO.getCode()); // 模块代码：整改后照片
                        log.info("改造后照片上传成功，附件ID={}", afterAttId);
                    } catch (Exception e) {
                        log.error("改造后照片上传失败：{}", data.getAfterImagePath(), e);
                    }
                }
                
                successCount++;
                log.info("✅ 整改数据保存成功：序号={}, 车间={}, 具体点位={}", 
                        data.getSerialNumber(), data.getWorkshop(), data.getSpecificLocation());
                
            } catch (Exception e) {
                failCount++;
                log.error("❌ 整改数据保存失败：序号={}, 车间={}, 错误：{}", 
                        data.getSerialNumber(), data.getWorkshop(), e.getMessage(), e);
            }
        }
        
        log.info("整改数据保存完成，成功：{}条，失败：{}条", successCount, failCount);
        
        // 保存完成后清空缓存列表（重要：防止数据重复）
        cachedDataList.clear();
    }
}

